//#include <stdio.h>
//#include "headfile.h"
//#include <iostream>
//using namespace std;
#include "stdafx.h"

#define CODE_PAGE_CP65001 0
#define CODE_PAGE_CP932 1
#define CODE_PAGE_CP936 2
#define charcode_high bom1
#define charcode_low bom2

static int GetNewCueName(WCHAR * newcuename,char * utfnewcuename)
{
	WCHAR * szchartochange;
	int size;
	size = wcslen(newcuename)+1;
	szchartochange = (WCHAR *)malloc(sizeof(WCHAR)*size);
	wcscpy_s(szchartochange,size,newcuename);
	size = WideCharToMultiByte(65001,NULL,szchartochange,-1,NULL,0,NULL,FALSE);
	if(!utfnewcuename)
	{
		free(szchartochange);
		return size;
	}
	WideCharToMultiByte(65001,NULL,szchartochange,-1,utfnewcuename,size,NULL,FALSE);
	free(szchartochange);
	return 0;
}

static void SetBOM(FILE *target)
{
	fputc(0xEF,target);
	fputc(0xBB,target);
	fputc(0xBF,target);
}
//there is some code couldn't detect
static unsigned short int GetCodePage(WCHAR * targetcue)
{
//utf-8 file with bom
//read bom to judge file 
	FILE * read;
	register unsigned short int bom1,bom2,bom3;
	if((_wfopen_s(&read,targetcue,(L"r+"))) !=0 )
	{
		wprintf(L"Cann't open file\n");
		exit (1);							// this is an error return
	}
	bom1 = (unsigned short int)fgetc(read);
	bom2 = (unsigned short int)fgetc(read);
	bom3 = (unsigned short int)fgetc(read);
	if(bom1==0xEF&&bom2==0xBB&&bom3==0xBF)	//EF ==  239 BB == 187 BF == 191 three bom in utf-8 file
	{
		fclose(read);
		return CODE_PAGE_CP65001;
	}
	else
	{}
	rewind(read);							//reset value to use
	charcode_high = 0;
	charcode_low = 0;
	while(!feof(read))
	{
		//the char is asc ii
		if(charcode_high <= 0x7F)
		{
			charcode_high = fgetc(read);
		}
		//the char is mutli byte
		else
		{
			charcode_low = fgetc(read);
			//charcode_high is in jis block 1
			if((0x81<=charcode_high)&&(charcode_high<=0x9F)||
				(0xE0<=charcode_high)&&(charcode_high<=0xEF))
			{
				if((0x40<=charcode_low)&&(charcode_low<=0x7E)||
				(0x80<=charcode_low)&&(charcode_low<=0xFC))
				{
					//this char pass the test
					charcode_high = fgetc(read);
				}
				else
				{
					//this char not pass the test
					//we just test 2 code page
					fclose(read);
					return CODE_PAGE_CP936;
				}
			}
			//char code_high is in jis block 2
			else if((0xA1<= charcode_high)&&(charcode_high<=0xDF))
			{
				charcode_high = charcode_low;
			}
			//char code_high is not in jis
			else
			{
				fclose(read);
				return CODE_PAGE_CP936;
			}
		}
	}
	//complete the char test
	//we regard it as jis
	fclose(read);
	return CODE_PAGE_CP932;
}
static void CodePageChange(FILE * read,FILE * create,char char_high,unsigned short int codepage)
{
	if(codepage != 0)
	{
		unsigned int codepagenum[3] ={65001,932,936};
		unsigned int codepagecode = codepagenum[codepage];
		char mtext[3];
		if((unsigned int)char_high <= 0x7F)	//asc ii char do not change
		{
			fputc(char_high,create);
		}
		else
		{
			char char_low = fgetc(read);
			mtext[0] = char_high;
			mtext[1] = char_low;
			mtext[2] = '\0';
			DWORD dwNum = MultiByteToWideChar(codepagecode,NULL,mtext,-1,NULL,0);
			wchar_t * wtext;
			wtext = new wchar_t[dwNum];
			if(!wtext)
			{
				delete []wtext;
			}
			//change char to Unicode
			MultiByteToWideChar(codepagecode,NULL,mtext,-1,wtext,dwNum);
			dwNum = WideCharToMultiByte(65001,NULL,wtext,-1,NULL,0,NULL,FALSE);
			char * char_changed;
			char_changed = (char *)malloc(sizeof(char)*dwNum);
			if(!char_changed)
			{
				free(char_changed);
			}
			//change char to utf-8
			WideCharToMultiByte(65001,NULL,wtext,-1,char_changed,dwNum,NULL,FALSE);
			delete []wtext;
			fputs(char_changed,create);
			free(char_changed);
		}
	}
	else
	{
		fputc(char_high,create);
	}
}
//replace the cue name in new cue
static void NewCueCreate(WCHAR * newcuename,FILE * read,FILE * create,unsigned short int codepage)
{
	char char_high;
	char * buffer;
	char * utfnewcuename;
	utfnewcuename = (char *)malloc(sizeof(char)*GetNewCueName(newcuename,NULL));
	GetNewCueName(newcuename,utfnewcuename);
	buffer = (char *)malloc(sizeof(char)*10);
	char * aim = "FILE \"";
	short int result;
	// this block of code  is to replace the cue name
	while(!feof(read))
	{
		char_high = fgetc(read);
		CodePageChange(read,create,char_high,codepage);
		if(char_high == 0x0A)
		{
			fgets(buffer,7,read);
			fputs(buffer,create);
			result = strcmp(buffer,aim);
			if(result == 0)
			{
				
				fprintf(create,"%s\" WAVE",utfnewcuename);        //do change the content to CDImage+num+.+suffix
				free(buffer);
				break;
			}
			else
			{}
		}
		else
		{}
	}
	//scape the rest of the line FILE "xxxxxxxxxx" WAVE
	char_high = fgetc(read);
	while(char_high != 0x0A)
	{
		char_high = fgetc(read);
	}
	//do change code in rest of content
	while(!feof(read))
	{
		CodePageChange(read,create,char_high,codepage);
		char_high = fgetc(read);
	}
}


extern unsigned short int ChangeContent(WCHAR * cuetochange,WCHAR * cuechanged,WCHAR * newcuename)
{
	FILE * cue_read,* cue_create;
	unsigned short int codepage;
	codepage = GetCodePage(cuetochange);
	if((_wfopen_s(&cue_read,cuetochange,(L"r+"))) !=0)
	{
		wprintf(L"Cannot open the file");		//could't open file exit error
		exit (1);
	}
	else
	{
		if((_wfopen_s(&cue_create,cuechanged,(L"w+"))) != 0)
		{
			wprintf(L"Cannot create cue file");
			exit (1);
		}
		else
		{}
	}
	// occording to the codepage to change content
	// cp932 & cp936 we should mark bom first
	switch(codepage)
	{
	case CODE_PAGE_CP932:
	case CODE_PAGE_CP936:
		SetBOM(cue_create);	
	case CODE_PAGE_CP65001:
		NewCueCreate(newcuename,cue_read,cue_create,codepage);break;
	};
	fclose(cue_read);
	fclose(cue_create);
	return 0;
}
